home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / BARNET / COMPILER / SATHER / !Sather / Library / Base / sa / int < prev    next >
Text File  |  1996-08-03  |  28KB  |  892 lines

  1. ---------------------------> Sather 1.1 source file <--------------------------
  2. -- Copyright (C) International Computer Science Institute, 1994.  COPYRIGHT  --
  3. -- NOTICE: This code is provided "AS IS" WITHOUT ANY WARRANTY and is subject --
  4. -- to the terms of the SATHER LIBRARY GENERAL PUBLIC LICENSE contained in    --
  5. -- the file "Doc/License" of the Sather distribution.  The license is also   --
  6. -- available from ICSI, 1947 Center St., Suite 600, Berkeley CA 94704, USA.  --
  7. --------> Please email comments to "sather-bugs@icsi.berkeley.edu". <----------
  8.  
  9. -- int.sa: Built-in integers.
  10. -------------------------------------------------------------------
  11. immutable class INT < $NUMBER{INT}, $HASH, $FMT is
  12.    -- The most fundamental integer class. Signed, unsigned, and modular
  13.    -- versions of arithmetic operations are provided. The names of
  14.    -- unsigned operations begin with the letter "u". The names of 
  15.    -- modular operations begin with the letter "m". Negative numbers 
  16.    -- are represented using 2's complement. INT objects inherit from
  17.    -- AVAL{BOOL}. The number of bits in the representation is `asize'
  18.    -- and is implementation dependent. It must be at least 32, however 
  19.    -- (to ensure portability of INT literals up to this size). Many of 
  20.    -- the operations are specified to raise exceptions on overflow. They 
  21.    -- are guaranteed to do this if checking is enabled, but this may 
  22.    -- affect performance. Certain machines (with appropriate hardware) 
  23.    -- may perform these checks even when checking is not enabled. The 
  24.    -- modular operations are performed modulo 2^asize. 
  25.    -- 
  26.    -- References:
  27.    -- Keith O. Geddes, Stephen R. Czapor, and George Labahn, "Algorithms
  28.    -- for Computer Algebra", Kluwer Academic Publishers, Boston, 1992.
  29.    
  30.    -- AVAL does not work yet.  For the moment leave out.
  31.    -- include AVAL{BOOL} asize->;
  32.    include COMPARABLE;
  33.    
  34.    const asize:INT:=32;
  35.    -- Size in bits.  
  36.    
  37.    -- Signed operations:
  38.    
  39.    plus(i:SAME):SAME is builtin INT_PLUS; end;
  40.    -- The signed sum of self and `i'. Raises an exception on 
  41.    -- overflow, when enabled. Built-in.
  42.    
  43.    minus(i:SAME):SAME is builtin INT_MINUS; end;   
  44.    -- The signed difference between self and `i'. Raises an exception
  45.    -- on overflow, when enabled. Built-in.     
  46.    
  47.    negate:SAME is builtin INT_NEGATE; end;
  48.    -- The signed negation of self. Same as zero minus self.
  49.    -- Only raises an exception on the most negative value (which
  50.    -- doesn't have a corresponding positive value in 2's complement.)
  51.    -- Built-in.
  52.    
  53.    times(i:SAME):SAME is builtin INT_TIMES; end;
  54.    -- The signed product of self and `i'. Raises an exception if the
  55.    -- product can't be held in the result, when enabled. Built-in.
  56.    
  57.    div(i:SAME):SAME is builtin INT_DIV; end;   
  58.    -- The signed quotient of self and `i'. This and `mod' have the 
  59.    -- property that for non-zero `y', `x=x.div(y)*x + x.mod(y)'. Raises
  60.    -- an exception when `i' is 0, when enabled. Built-in.            
  61.    
  62.    mod(i:SAME):SAME is builtin INT_MOD; end;   
  63.    -- Signed remainder of self divided by `i'. This and `mod' have the 
  64.    -- property that for non-zero `y', `x=x.div(y)*x + x.mod(y)'. It's
  65.    -- also true that `0 <= x.mod(y) < y.abs'. Raises an exception when
  66.    -- `i' is 0, when enabled. Built-in.        
  67.  
  68.    is_eq(i:SAME):BOOL is builtin INT_IS_EQ; end;
  69.    -- True if self and `i' represent the same value.
  70.    -- return self=i 
  71.  
  72.    is_lt(i:SAME):BOOL is builtin INT_IS_LT; end;   
  73.    -- True if self is less than `i' as signed integers. Built-in.
  74.    
  75.    max(i:SAME):SAME is builtin INT_MAX; end;
  76.    -- The larger of self and `i' as signed integers.  Built-in.
  77.  
  78.    min(i:SAME):SAME is builtin INT_MIN; end;
  79.    -- The smaller of self and `i' as signed integers.  Built-in.
  80.    
  81.    at_least(x:SAME):SAME is
  82.       -- Same as `max(x)'.
  83.       return max(x)
  84.    end;
  85.    
  86.    at_most(x:SAME):SAME is
  87.       -- Same as `min(x)'.
  88.       return min(x)
  89.    end;
  90.    
  91.    within(x,y:SAME):SAME is
  92.       -- Same as `max(x).min(y)'.
  93.       return max(x).min(y)
  94.    end;
  95.  
  96.    -- Conversion from other types:
  97.    
  98.    create(x:INT):SAME is return x end;
  99.    create(x:INTI):SAME is return x.int end;
  100.    create(f:FLT):SAME is return f.int end;
  101.    create(f:FLTD):SAME is return f.int end;
  102.    
  103.    create(s:STR): SAME is builtin INT_CREATE_STR; end;
  104.    
  105.    int:INT is builtin INT_INT; end;
  106.    -- An integer version of self.
  107.    
  108.    from_int(i:INT):SAME is
  109.       -- Returns `i'.
  110.       return i
  111.    end;
  112.    
  113.    inti:INTI is
  114.       -- An infinite precision version of self.
  115.       return #INTI(self)
  116.    end;
  117.    
  118.    flt:FLT is builtin INT_FLT; end;
  119.    -- A floating point version of self. It is an error if the
  120.    -- value cannot be held in a FLT.  Built-in.
  121.    
  122.    fltd:FLTD is builtin INT_FLTD; end;
  123.    -- A double floating point version of self. It is an error
  124.    -- if the value cannot be held in a FLTD.  Built-in.
  125.    
  126.    
  127.    bool:BOOL is builtin INT_BOOL; end;
  128.    -- A boolean from self.  Built-in.
  129.    
  130.    char:CHAR is builtin INT_CHAR; end;
  131.    -- A character corresponding to the value of self. Built-in.
  132.  
  133.    c_unsigned_int:C_UNSIGNED_INT is builtin INT_C_UNSIGNED_INT; end;
  134.    -- Convert to external C unsigned integer.  Built-in.
  135.  
  136.    -- Other computation:
  137.    
  138.    abs:SAME is builtin INT_ABS; end;
  139.    -- The absolute value of self.  Built-in.
  140.    
  141.    square:SAME is builtin INT_SQUARE; end;
  142.    -- The square of self.  Built-in.
  143.    
  144.    cube:SAME is
  145.       -- The cube of self.
  146.       return self*self*self
  147.    end;
  148.  
  149.    pow(i:INT):SAME
  150.    -- Self raised to the power `i'.
  151.       pre i>=0 is
  152.       r:SAME;
  153.       case i 
  154.       when 0 then return 1       
  155.       when 1 then return self
  156.       when 2 then return self*self     
  157.       when 3 then return self*self*self
  158.       when 4 then r:=self*self; return r*r
  159.       when 5 then r:=self*self; return self*r*r
  160.       when 6 then r:=self*self; return r*r*r
  161.       when 7 then r:=self*self; return self*r*r*r
  162.       when 8 then r:=self*self; r:=r*r; return r*r
  163.       when 9 then r:=self*self; r:=r*r; return self*r*r
  164.       when 10 then r:=self*self; r:=self*r*r; return r*r
  165.       else
  166.      x ::= self; r := 1;
  167.      loop
  168.         -- r * x^i = self ^ i0
  169.         if i.is_odd then r := r*x end;
  170.         i := i.rshift(1);
  171.         while!(i>0);
  172.         x := x.square;
  173.      end;
  174.      return r;
  175.       end;
  176.    end;
  177.    
  178.    sqrt:SAME 
  179.    -- The largest integer whose square is smaller than self.
  180.       pre self>=0
  181.    is
  182.       x::=fltd;
  183.       r:SAME;
  184.       if self=x.floor.int then return x.sqrt.floor.int
  185.       else q::=1; r:=self; 
  186.      loop while!(q<=r); q:=4*q end;
  187.      loop while!(q/=1); q:=q/4; h::=r+q; r:=r/2; 
  188.         if h<=r then r:=r-h; r:=r+q end end end;
  189.       return r
  190.    end;
  191.    
  192.    exp2:SAME pre self>=0 is return 0.set_bit(self) end;
  193.    
  194.    ten_pow:SAME pre self>=0 is return exp10 end;
  195.    
  196.    exp10:SAME
  197.    -- Ten to the self power. Small values use lookup table for speed.
  198.       pre self>=0
  199.    is
  200.       case self
  201.       when 0 then return 1 
  202.       when 1 then return 10 
  203.       when 2 then return 100
  204.       when 3 then return 1000 
  205.       when 4 then return 10000 
  206.       when 5 then return 100000
  207.       when 6 then return 1000000 
  208.       when 7 then return 10000000
  209.       when 8 then return 100000000 
  210.       when 9 then return 1000000000
  211.       else return 10.pow(self) end
  212.    end;
  213.    
  214.    num_digits:INT
  215.    -- The number of decimal digits in non-negative self.
  216.    -- Use binary search so that small values take only 3 compares.
  217.       pre self>=0 is
  218.       if self<10000 then
  219.      if self<100 then 
  220.         if self<10 then return 1 else return 2 end
  221.      else if self<1000 then return 3 else return 4 end end;
  222.       else
  223.      if self<1000000 then 
  224.         if self<100000 then return 5 else return 6 end
  225.      else
  226.         return (self/10000).num_digits+4;
  227.         --r::=7; tst::=10000000;
  228.         --loop 
  229.         --   if self<tst then return r end; 
  230.         --   r:=r+1; tst:=tst*10 end;
  231.         --raise "INT::num_digits error."
  232.      end
  233.       end
  234.    end;
  235.    
  236.    hash:INT is
  237.       r::=self;
  238.       
  239.       -- We should try to get numbers away from each other, even if
  240.       -- they don't collide.  For example, if SYS::id returns
  241.       -- objects in consecutive aligned positions, we don't want to
  242.       -- end up returning successive integers.  Unfortunately, it's
  243.       -- not good enough to just multiply/add by some magic numbers,
  244.       -- because that doesn't affect the randomness once passed
  245.       -- through a mod function (for instance FSET etc. just use the
  246.       -- rightmost bits, equivalent to mod by a power of two.)  Here
  247.       -- a few steps of a shift generator are done.
  248.       r:=r.bxor(r.lshift(17));
  249.       r:=r.bxor(r.urshift(15));
  250.       r:=r.bxor(r.lshift(17));
  251.       r:=r.bxor(r.urshift(15));
  252.       r:=r.bxor(r.lshift(17));
  253.       r:=r.bxor(r.urshift(15));
  254.       return r;
  255.    end;
  256.  
  257.    -- Conversion into printable forms:
  258.    
  259.    str_in (s: FSTR, n, b: INT, f: CHAR): FSTR pre b.is_bet(2, 16) is
  260.       -- Append a string representation of self to s using at least n digits
  261.       -- to the base b and return s. If less then n digits are used for the
  262.       -- representation of self (including its sign), the remaining left_most
  263.       -- positions are filled with character f.
  264.       --
  265.       if is_nil then 
  266.      -- The nil value  (most negative number) cannot be negated - 
  267.      -- due to the inherent assymetry of the representation.
  268.      -- There is no corresponding positive number
  269.      x ::= self;
  270.      divid: INT := x/b;
  271.      rem1: INT := (x - divid*(b-1));
  272.      rem: INT := rem1-divid;
  273.      if rem > 0 then rem := rem-b;  divid := divid + 1; end;
  274.      -- If divid was rounded up instead of down,manually divid to divid-1
  275.      first_char: CHAR := rem.abs.digit_char;
  276.      x := divid.abs;
  277.      i ::= s.length;
  278.      s := s+first_char;
  279.      n := n - 1;
  280.      loop s := s + (x%b).digit_char; x := x/b; n := n-1; until!(x = 0) end;
  281.      s := s + '-'; n := n-1;
  282.      loop while!(n > 0); s := s + f; n := n-1 end;
  283.      j ::= s.length-1;
  284.      loop while!(i < j); 
  285.         ch ::= s[i]; s[i] := s[j]; s[j] := ch; i := i+1; j := j-1 
  286.      end;
  287.      return s;
  288.      -- return #INTI(nil).str_in(s, n, b, f)
  289.      --#FSTR("nil");
  290.       else
  291.      x ::= self.abs; i ::= s.length;
  292.      loop s := s + (x%b).digit_char; x := x/b; n := n-1; until!(x = 0) end;
  293.      if self < 0 then s := s + '-'; n := n-1 end;
  294.      loop while!(n > 0); s := s + f; n := n-1 end;
  295.      j ::= s.length-1;
  296.      loop while!(i < j); 
  297.         ch ::= s[i]; s[i] := s[j]; s[j] := ch; i := i+1; j := j-1 
  298.      end;
  299.      return s
  300.       end
  301.    end;
  302.    
  303.    
  304.    str_in(s:FSTR):FSTR is
  305.       -- Append a decimal string version of self to `s' and return it.
  306.       return str_in(s, 0, 10, ' ')
  307.    end;
  308.    
  309.    -- the shared buffer is actually faster, but not thread safe.
  310.    -- private shared buf:FSTR;    -- Buffer for string output.   
  311.    
  312.    str:STR is
  313.       buf:FSTR;
  314.       -- A decimal string version of self.
  315.       buf.clear; buf:=str_in(buf); return buf.str
  316.    end;
  317.    
  318.    fmt( f: STR ): STR
  319.    is
  320.       return BASE_FORMAT::fmt_int(self,f)
  321.    end;
  322.    
  323.    digit_char:CHAR
  324.    -- A character representing self. If self is between 0 and 9, it
  325.    -- returns a digit. If between 10 and 15, returns 'A' thru 'F'.
  326.       pre self.is_bet(0,15) is
  327.       return "0123456789ABCDEF"[self]
  328.    end;
  329.  
  330.    -- Integer properties:
  331.    
  332.    is_even:BOOL is builtin INT_IS_EVEN; end;
  333.    
  334.    is_odd:BOOL is builtin INT_IS_ODD; end;
  335.    
  336.    is_pos:BOOL is
  337.       -- True if self is greater than zero.
  338.       return self>0
  339.    end;
  340.    
  341.    is_neg:BOOL is
  342.       -- True if self is less than zero.
  343.       return self<0
  344.    end;
  345.    
  346.    is_zero:BOOL is
  347.       -- True if self is zero.
  348.       return self=0
  349.    end;
  350.    
  351.    is_non_zero:BOOL is
  352.       -- True if self is non-zero.
  353.       return self/=0
  354.    end;
  355.    
  356.    is_non_neg:BOOL is
  357.       -- True if self is non-negative.
  358.       return self>=0
  359.    end;
  360.    
  361.    is_non_pos:BOOL is
  362.       -- True if self is non-positive.
  363.       return self<=0
  364.    end;
  365.    
  366.    sign:SAME is
  367.       -- -1,0,1 depending on the sign of self.
  368.       -- Steele, 304
  369.       if self<0 then return -1 
  370.       elsif self>0 then return 1 
  371.       else return 0 end
  372.    end;
  373.    
  374.    is_bet(l,u:SAME):BOOL is builtin INT_IS_BETWEEN; end;
  375.    -- True if self between l and u.  Built-in.
  376.    
  377.    is_between(l,u:SAME):BOOL is builtin INT_IS_BETWEEN; end;
  378.    -- True if self between l and u.  Built-in.
  379.    
  380.    is_within(tolerance,val:SAME):BOOL is
  381.       return (self-val).abs<=tolerance;
  382.    end;
  383.    
  384.    is_eq(i1,i2:SAME):BOOL is
  385.       -- True if self equals `i1' and `i2'.
  386.       return self=i1 and self=i2 end;
  387.    
  388.    is_eq(i1,i2,i3:SAME):BOOL is
  389.       -- True if self equals `i1', `i2', and `i3'.
  390.       return self=i1 and self=i2 and self=i3 end;   
  391.    
  392.    nil:SAME is
  393.       -- The value to be used to represent no element in sets.
  394.       -- The most negative value.
  395.       return 1.lshift(asize-1)
  396.    end;
  397.    
  398.    is_nil:BOOL is return self=1.lshift(asize-1); end;
  399.    
  400.    -- Unsigned operations:   
  401.    
  402.    uplus(i:SAME):SAME is builtin INT_UPLUS; end;
  403.    -- The unsigned sum of self and `i'. Raises an exception on 
  404.    -- overflow, when enabled. Built-in.      
  405.    
  406.    uminus(i:SAME):SAME is builtin INT_UMINUS; end;
  407.    -- The unsigned difference between self and `i'. Raises an 
  408.    -- exception on overflow or if the result would be negative,
  409.    -- when enabled. Built-in.      
  410.    
  411.    utimes(i:SAME):SAME is builtin INT_UTIMES; end;
  412.    -- The unsigned product of self and `i'. Raises an exception if the
  413.    -- product can't be held in the result, when enabled. Built-in.
  414.    
  415.    udiv(i:SAME):SAME is builtin INT_UDIV; end;
  416.    -- The unsigned quotient of self and `i'. Raises an exception when
  417.    -- `i' is 0, when enabled. Built-in.            
  418.    
  419.    umod(i:SAME):SAME is builtin INT_UMOD; end;
  420.    -- Unsigned remainder of self divided by `i'. Raises an exception 
  421.    -- when `i' is 0, when enabled. Built-in.            
  422.  
  423.    is_ult(lhs:SAME):BOOL is
  424.       if self>=0 and lhs<0 then return true end;
  425.       if self<0 and lhs>=0 then return false end;
  426.       -- both (self and lhs) have the same sign
  427.       return self<lhs;
  428.    end;
  429.    
  430.    is_uleq(i:SAME):BOOL is
  431.       -- True if self is less than or equal to `i' as unsigned integers.
  432.       return is_ult(i) or self=i
  433.    end;   
  434.    
  435.    is_ugt(i:SAME):BOOL is
  436.       -- True if self is greater than `i' as unsigned integers.
  437.       return i.is_ult(self)
  438.    end;
  439.    
  440.    is_ugeq(i:SAME):BOOL is
  441.       -- True if self is greater than or equal to `i' as unsigned 
  442.       -- integers.
  443.       return i.is_ult(self) or self=i
  444.    end;
  445.    
  446.    umax(i:SAME):SAME is
  447.       -- The larger of self and `i' as unsigned integers.
  448.       if self.is_ugt(i) then return self else return i end
  449.    end;
  450.    
  451.    umin(i:SAME):SAME is
  452.       -- The smaller of self and `i' as unsigned integers.
  453.       if self.is_ult(i) then return self else return i end
  454.    end;
  455.    
  456.    evenly_divides(i:SAME):BOOL is
  457.       -- True if self evenly divides `i'.
  458.       return i%self=0
  459.    end;
  460.    
  461.    next_multiple_of(i:SAME):SAME 
  462.    -- The smallest value greater than or equal to self which is a 
  463.    -- multiple of `i'. 
  464.       pre i>0 is
  465.       return ((self+i-1)/i)*i
  466.    end;
  467.    
  468.    gcd(i:SAME):SAME is
  469.       -- The greatest common divisor of self and `i'.
  470.       -- The result is non-negative and `x.gcd(0)=x.abs'.
  471.       -- Uses Euclidean algorithm. Geddes, et. al. p. 34.
  472.       c::=abs; d::=i.abs;
  473.       loop until!(d=0); r::=c.mod(d); c:=d; d:=r end; 
  474.       return c
  475.    end;
  476.  
  477.    extended_gcd(i:SAME, out self_factor,out i_factor: SAME): SAME is
  478.       -- The three parts of the return value `g', `g1', and `g2' are such
  479.       -- that `g' is the greatest common divisor of self and `i' and
  480.       -- `g1*self+g2*i=g'.
  481.       -- Uses the extended Euclidean algorithm. Geddes, et. al. p. 36.
  482.       c::=abs; d::=i.abs; c1::=1; d1::=0; c2::=0; d2::=1;
  483.       loop until!(d=0);
  484.      q::=c/d; r::=c-q*d; r1::=c1-q*d1; r2::=c2-q*d2;
  485.      c:=d; c1:=d1; c2:=d2; d:=r; d1:=r1; d2:=r2 
  486.       end;
  487.       self_factor :=  c1/(abs*c.abs);
  488.       i_factor := c2/(abs*c.abs);
  489.       return c.abs;
  490.    end;
  491.    
  492.    lcm(i:SAME):SAME is
  493.       -- The least common multiple of self and `i'.
  494.       -- Geddes, et. al. p. 28.      
  495.       return (self*i).abs/gcd(i)
  496.    end;
  497.    
  498.    is_prime:BOOL is
  499.       -- True if self is a prime number.
  500.       -- Replace by a faster algorithm.
  501.       if 2.evenly_divides(self) then return false end;
  502.       loop
  503.      d::=3.step!((self.sqrt+2)/2, 2);
  504.      if d.evenly_divides(self) then return false end
  505.       end; 
  506.       return true
  507.    end;
  508.    
  509.    is_relatively_prime_to(i:SAME):BOOL is
  510.       -- True if self is relatively prime to `i'.
  511.       return gcd(i)=1
  512.    end;
  513.     
  514.    factorial:SAME is
  515.       -- The factorial of self.
  516.       -- Replace by faster algorithm.
  517.       p::=1;
  518.       loop p:=p*2.upto!(self) end;
  519.       return p
  520.    end;
  521.    
  522.    -- Operations modulo 2^asize:
  523.    
  524.    mplus(i:SAME):SAME is builtin INT_MPLUS; end;
  525.    -- The sum of self and `i' modulo 2^asize. Never raises
  526.    -- an exception. Built-in.      
  527.    
  528.    mminus(i:SAME):SAME is builtin INT_MMINUS; end;
  529.    -- The difference between self and `i' modulo 2^asize. Never
  530.    -- raises an exception. Built-in.      
  531.    
  532.    mnegate:SAME is builtin INT_MNEGATE; end;
  533.    -- The additive inverse of self modulo 2^asize. Never raises an
  534.    -- exception. 
  535.    
  536.    mtimes(i:SAME):SAME is builtin INT_MTIMES; end;
  537.    -- The product of self and `i' modulo 2^asize. Never raises
  538.    -- an exception. Built-in.
  539.    
  540.    mdiv(i:SAME):SAME is builtin INT_MDIV; end;
  541.    -- The unsigned quotient of self and `i'. Raises an exception when
  542.    -- `i' is 0, when enabled. Built-in.            
  543.    
  544.    mmod(i:SAME):SAME is builtin INT_MMOD; end;
  545.    -- Unsigned remainder of self divided by `i'. Raises an exception 
  546.    -- when `i' is 0, when enabled. 
  547.    
  548.    -- Bitwise operations:
  549.    
  550.    bnot:SAME is builtin INT_BNOT; end;
  551.    -- The bitwise complement of self.
  552.    
  553.    band(i:SAME):SAME is builtin INT_BAND; end;
  554.    -- The bitwise and of self and `i'.
  555.    
  556.    bor(i:SAME):SAME is builtin INT_BOR; end;
  557.    -- The bitwise inclusive or of self and `i'.
  558.    
  559.    bxor(i:SAME):SAME is builtin INT_BXOR; end;
  560.    -- The bitwise exclusive or of self and `i'.
  561.    
  562.    bnand(i:SAME):SAME is
  563.       -- The bitwise nand of self and `i'.
  564.       return band(i).bnot end;
  565.    
  566.    bnor(i:SAME):SAME is
  567.       -- The bitwise nor of self and `i'.
  568.       return bor(i).bnot end;
  569.    
  570.    beqv(i:SAME):SAME is
  571.       -- The bits of res are 1 in positions where self and `i' have the
  572.       -- same bit values.
  573.       return bxor(i).bnot end;      
  574.    
  575.    boole(i:SAME, rule:INT):SAME 
  576.    -- The bits of res are combinations of the corresponding bits of
  577.    -- self and `i' combined according to a rule specified by `rule'. 
  578.    -- This must be a value between 0 and 15. The low order bit says 
  579.    -- what to map a 0 in self and a 0 in `i' to, the second bit of
  580.    -- `rule' says what to map 0,1 to, the third bit defines 1,0 and 
  581.    -- the fourth 1,1.
  582.       pre rule.is_bet(0,15) is
  583.       case rule when 0 then return 0         
  584.       when 1 then return bor(i).bnot
  585.       when 2 then return bnot.band(i)   
  586.       when 3 then return bnot
  587.       when 4 then return band(i.bnot)   
  588.       when 5 then return i.bnot
  589.       when 6 then return bxor(i)         
  590.       when 7 then return band(i).bnot
  591.       when 8 then return band(i)        
  592.       when 9 then return bxor(i).bnot
  593.       when 10 then return i             
  594.       when 11 then return bnot.bor(i)
  595.       when 12 then return self            
  596.       when 13 then return bor(i.bnot)
  597.       when 14 then return bor(i)        
  598.       when 15 then return -1 
  599.       else raise "INT::boole(SAME,INT):SAME err."
  600.       end
  601.    end;
  602.    
  603.    bcount:INT is
  604.       -- The number of bits in self which are set to 1.
  605.       r:SAME;
  606.       if asize=32 then
  607.      -- 32 bit version:
  608.      r:=self.band(0b01010101010101010101010101010101)
  609.            .uplus(self.urshift(1)
  610.               .band(0b01010101010101010101010101010101));
  611.      r:=r.band(0b00110011001100110011001100110011)
  612.            .uplus(r.urshift(2).band(0b00110011001100110011001100110011));
  613.      r:=r.band(0b00001111000011110000111100001111)
  614.            .uplus(r.urshift(4).band(0b00001111000011110000111100001111));
  615.      r:=r+r.rshift(8); 
  616.      r:=(r+r.rshift(16)).band(0b111111);
  617.      -- No need to mask the last two steps since the bits can't 
  618.      -- interfere.
  619.       else
  620.      -- General size.
  621.      -- Semi-clever version (fast when sparse but slow for dense):
  622.      x::=self; 
  623.      loop until!(x=0); x:=x.band(x.uminus(1)); r:=r+1 end;
  624.       end;
  625.       return r
  626.    end;
  627.    
  628.    lshift(i:INT):SAME is builtin INT_LSHIFT; end;
  629.    -- The bits of self shifted left by `i' places with
  630.    -- zeroes shifted in on the right.
  631.    
  632.    rshift(i:INT):SAME is builtin INT_RSHIFT; end;
  633.    -- The bits of self shifted right by `i' places with
  634.    -- bits equal to the first bit of self shifted in on the left.
  635.    
  636.    urshift(i:INT):SAME is builtin INT_URSHIFT; end;
  637.    -- The bits of self shifted right by `i' places with
  638.    -- zeroes shifted in on the left.
  639.    
  640.    lrotate(i:INT):SAME
  641.    -- Left rotate the bits of self by `i' places.
  642.       pre i.is_bet(0,asize)
  643.    is
  644.       return lshift(i).bor(urshift(asize-i))
  645.    end;
  646.    
  647.    rrotate(i:INT):SAME
  648.    -- Right rotate the bits of self by `i' places.
  649.       pre i.is_bet(0,asize)
  650.    is
  651.       return urshift(i).bor(lshift(asize-i))
  652.    end;
  653.  
  654.    bit(i:INT):BOOL is
  655.       -- True if bit `i' of self is 1.
  656.       return band(1.lshift(i))/=0
  657.    end;
  658.    
  659.    set_bit(i:INT,b:BOOL):SAME is
  660.       -- Self with bit `i' set to b.
  661.       if b then return set_bit(i) else return unset_bit(i) end
  662.    end;
  663.    
  664.    set_bit(i:INT):SAME is
  665.       -- Self with bit `i' set to 1.
  666.       return bor(1.lshift(i))
  667.    end;
  668.    
  669.    unset_bit(i:INT):SAME is
  670.       -- Self with bit `i' set to 0.
  671.       return band((1.lshift(i)).bnot)
  672.    end;
  673.    
  674.    octal_str:STR is
  675.       -- The octal representation of self of the form "0o15".
  676.       -- Self is interpreted as an unsigned integer.
  677.       buf:FSTR;
  678.       buf.clear; i::=self;
  679.       loop
  680.      buf:=buf + i.band(7).digit_char; 
  681.      i:=i.urshift(3);
  682.      until!(i=0)
  683.       end;
  684.       buf:=buf + "o0"; 
  685.       buf.to_reverse;
  686.       return buf.str
  687.    end;
  688.    
  689.    binary_str:STR is
  690.       -- The binary representation of self of the form "0b100100".
  691.       -- Self is interpreted as an unsigned integer.
  692.       buf:FSTR;
  693.       buf.clear; i::=self;
  694.       loop
  695.      buf := buf + i.band(1).digit_char; 
  696.      i:=i.urshift(1);
  697.      until!(i=0)
  698.       end;
  699.       buf:=buf + "b0"; 
  700.       buf.to_reverse;
  701.       return buf.str
  702.    end;
  703.    
  704.    hex_str:STR is
  705.       -- The hexadecimal representation of self of the form "0x5A".
  706.       -- Self is interpreted as an unsigned integer.
  707.       buf:FSTR;
  708.       buf.clear; i::=self;
  709.       loop
  710.      buf:=buf + i.band(15).digit_char; 
  711.      i:=i.urshift(4);
  712.      until!(i=0)
  713.       end;
  714.       buf:=buf + "x0"; 
  715.       buf.to_reverse;
  716.       return buf.str
  717.    end;
  718.    
  719.    lowest_bit:INT is
  720.       -- The position of the lowest non-zero bit of self. -1 if none.
  721.       if self=0 then return -1 end;
  722.       if asize=32 then
  723.      -- 32 bit version:
  724.      x::=self; r::=31;
  725.      z::=x.lshift(16); if z/=0 then x:=z; r:=r-16 end;
  726.      z:=x.lshift(8); if z/=0 then x:=z; r:=r-8 end;
  727.      z:=x.lshift(4); if z/=0 then x:=z; r:=r-4 end;
  728.      z:=x.lshift(2); if z/=0 then x:=z; r:=r-2 end;
  729.      z:=x.lshift(1); if z/=0 then x:=z; r:=r-1 end;
  730.      return r
  731.      -- 
  732.      -- This implementation assumes that asize is a power of 2.      
  733.      -- if self=0 then return -1 end;
  734.      -- x::=self; y::=asize/2; r:=asize-1;
  735.      -- loop until(y=0); z::=x.lshift(y);
  736.      -- if z/=0 then x:=z; r:=r-y end; y:=y.rshift(1) end; return r end;
  737.      -- 
  738.       else
  739.      -- Straightforward way:
  740.      loop i::=(asize-1).downto!(0);
  741.         if lshift(i)/=0 then r::=asize-i-1; return r end
  742.      end;
  743.      return -1;
  744.       end;
  745.    end;
  746.    
  747.    highest_bit:INT is
  748.       -- The position of the highest non-zero bit of self. -1 if none.
  749.       if self=0 then return -1 end;
  750.       if asize=32 then
  751.      -- 32 bit version:
  752.      x::=self; z::=x.urshift(16); r:INT;
  753.      if z/=0 then x:=z; r:=r+16 end;
  754.      z:=x.urshift(8); if z/=0 then x:=z; r:=r+8 end;
  755.      z:=x.urshift(4); if z/=0 then x:=z; r:=r+4 end;
  756.      z:=x.urshift(2); if z/=0 then x:=z; r:=r+2 end;
  757.      z:=x.urshift(1); if z/=0 then x:=z; r:=r+1 end;
  758.      return r;
  759.       else
  760.      --
  761.      -- This implementation assumes that asize is a power of 2.
  762.      -- if self=0 then return -1 end;      
  763.      -- x::=self; y::=asize/2;
  764.      -- loop until(y=0); z::=x.urshift(y);
  765.      --    if z/=0 then x:=z; r:=r+y end; y:=y.rshift(1) end; 
  766.      -- return r end;
  767.      --
  768.      -- Straightforward way:
  769.      loop i::=1.upto!(asize-1);
  770.         if rshift(i)=0 then return i-1 end
  771.      end;
  772.      return asize-1;
  773.       end; 
  774.    end;
  775.    
  776.    log2:INT pre self>0 is return self.highest_bit end;
  777.    
  778.    is_pow_of_2:BOOL is return is_exp2 end;
  779.    
  780.    is_exp2:BOOL is
  781.       -- returns true iff self is positive and a power of two
  782.       
  783.       res:BOOL:=false;
  784.       if self > 0 then
  785.      res := self.lowest_bit = self.highest_bit
  786.       end;
  787.       return res;
  788.    end;
  789.    
  790.    next_pow_of_2:INT is return next_exp2 end;
  791.    
  792.    next_exp2:INT is
  793.       -- for self positive it returns the p so that the following holds:
  794.       -- p.is_pow_of_2 and p>=self>(p/2)
  795.       
  796.       res:INT:=0;
  797.       bit:INT:=self.highest_bit;
  798.       if ~self.is_pow_of_2 then
  799.      bit := bit + 1;
  800.       end;
  801.       
  802.       return res.set_bit(bit); 
  803.    end;
  804.    
  805.    low_bits(i:INT):INT 
  806.    -- The low `i' bits of self with 0 in the higher positions.
  807.       pre i.is_bet(0,asize)
  808.    is
  809.       return band(1.lshift(i).uminus(1))
  810.    end;
  811.    
  812.    high_bits(i:INT):INT is
  813.       -- The high `i' bits of self with 0 in the lower positions.
  814.       return band((1.lshift(asize-i).uminus(1)).bnot)
  815.    end;
  816.    
  817.    aget(i:INT):BOOL is builtin INT_AGET; end;
  818.    aset(i:INT,j:BOOL):INT is builtin INT_ASET; end;
  819.    aelt!:BOOL is loop yield [asize.times!]; end; end;
  820.    
  821.    maxint:INT is builtin INT_MAXINT; end;
  822.    minint:INT is builtin INT_MININT; end;
  823.    
  824.    const zero:SAME := 0;                -- See $NUMBER.
  825.    const one: SAME := 1;
  826.    maxval:SAME is return maxint; end;    -- See $NUMBER.
  827.    minval:SAME is return minint; end;    -- See $NUMBER.
  828.    
  829.    -- Iters:
  830.    
  831.    times!  pre self>=0 is builtin INT_TIMESB; end;
  832.    -- Yields self times without returning anything.
  833.    
  834.    times!:SAME pre self>=0 is builtin INT_TIMESB_INT; end;
  835.    -- Yield successive integers from 0 up to self-1.
  836.    
  837.    for!(once i:SAME):SAME 
  838.    -- Yields `i' successive integers starting with self.
  839.       pre i>=0 is builtin INT_FORB;
  840.    end;
  841.    
  842.    up!:SAME is builtin INT_UPB; end;
  843.    -- Yield successive integers from self up.
  844.    
  845.    upto!(once i:SAME):SAME is builtin INT_UPTOB; end;
  846.    -- Yield successive integers from self to `i' inclusive.
  847.    
  848.    downto!(once i:SAME):SAME is builtin INT_DOWNTOB; end;
  849.    -- Yield successive integers from self down to `i' inclusive.
  850.    
  851.    step!(once num,once step:SAME):SAME 
  852.    -- Yield `num' integers starting with self and stepping by `step'.
  853.       pre num>=0
  854.    is 
  855.       r::=self; last::=self+(num-1)*step;
  856.       if step>0 then 
  857.      loop until!(r>last); yield r; r:=r+step end
  858.       elsif step<0 then 
  859.      loop until!(r<last); yield r; r:=r+step end
  860.       else 
  861.      loop num.times!; yield r end
  862.       end
  863.    end;
  864.  
  865.    stepto!(once to,once by:SAME): SAME
  866.    -- Yield succeeding integers from self to `to' by step `by'.
  867.    -- Might quit immediately if self is aleady `beyond'.
  868.       pre by /= 0
  869.    is
  870.       r ::= self;
  871.       if by>0 then
  872.      loop until!(r>to); yield r; r := r + by end
  873.       else
  874.      loop until!(r<to); yield r; r := r + by end
  875.       end
  876.    end;
  877.    
  878.    sum!(i:SAME):SAME is
  879.       -- Yields the sum of all previous values of `i'.
  880.       r:SAME;
  881.       loop r:=r+i; yield r end
  882.    end;
  883.    
  884.    product!(i:SAME):SAME is
  885.       -- Yields the product of all previous values of `i'.
  886.       r::=1;
  887.       loop r:=r*i; yield r end
  888.    end;
  889.     
  890. end; -- class INT
  891. -------------------------------------------------------------------
  892.